#include <appkit/application.h>
#include <appkit/basetype.h>
#include <appkit/console.h>
#include <appkit/tracer.h>

using namespace appkit;  // NOLINT

void test_async();
void test_fileio();
void test_serial();
void test_system();
void test_timer();
void test_network();

class MyComponent : public Component {
    DECL_CLASSMETA(MyComponent)

public:
    bool onInit() {
        TRACE_INFO_CLASS("Component init.");
        return true;
    }
    bool onStart() {
        TRACE_INFO_CLASS("Component start.");
        addTask([&]() {
            // 全生命周期任务:会一直占用一个任务线程直到app退出
            while (isRunning()) {
                TRACE_INFO_CLASS("running task.");
                Thread::msleep(1000);
            }
        });
        return true;
    }
    bool onStop() {
        TRACE_INFO_CLASS("Component stop.");
        return true;
    }
    bool onDeinit() {
        TRACE_INFO_CLASS("Component deinit.");
        return true;
    }
};

int main(int argc, char **argv) {
    ArgOption option;
    if (!option.parseArgs(argc, argv)) {
        return RC_ERROR;
    }
    if (option.hasOption("h") >= 0 || option.hasOption("help") >= 0) {
        PRINT_YELLOW("%s [-h | --help] [-d level]", argv[0]);
        return RC_OK;
    }

    int level = TRACE_LEVEL_INFO;
    if (option.hasOption("d") > 0) {
        level = std::stoi(option.getValue("d")[0]);
    }

    Tracer::getInstance().addSink(std::make_shared<STDSink>()).start();
    Tracer::getInstance().setLevel(level);

    bool running = true;
    Application app;
    app.registerSignal(SIGINT, [&]() {
        TRACE_WARN("signal SIGINT catched!");
        running = false;
    });  // 注册信号处理函数
    app.addComponent("MyComponent", std::make_shared<MyComponent>());
    {
        TraceDuration td("test", 10);
        Thread::msleep(10);
    }
    while (running) {
        TRACE_YELLOW("----------app test--------------");
        TRACE_YELLOW("00. application test");
        TRACE_YELLOW("01. async test");
        TRACE_YELLOW("02. serial test");
        TRACE_YELLOW("03. system test");
        TRACE_YELLOW("04. timer test");
        TRACE_YELLOW("05. fileio test");
        TRACE_YELLOW("06. network test");
        TRACE_YELLOW(" q. quit");
        TRACE_YELLOW("please input selection:");
        ConsoleIn ci;
        ci.waitInput();
        if (ci.asString() == "00") {
            app.startup(1);  // 使用一个任务线程
            while (running) {
                Thread::msleep(1000);
            }
            break;
        } else if (ci.asString() == "01") {
            test_async();
        } else if (ci.asString() == "02") {
            test_serial();
        } else if (ci.asString() == "03") {
            test_system();
        } else if (ci.asString() == "04") {
            test_timer();
        } else if (ci.asString() == "05") {
            test_fileio();
        } else if (ci.asString() == "06") {
            test_network();
        } else if (ci.asString() == "q" || ci.asString() == "quit") {
            break;
        }
    }
    app.quit();
    return RC_OK;
}
